package com.tydic.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tydic.system.domain.SysRole;
import com.tydic.system.domain.SysRoleMenu;
import com.tydic.system.domain.bo.QuerySysRoleBo;
import com.tydic.system.domain.bo.SysRoleBo;
import com.tydic.system.domain.vo.SysRoleVo;
import com.tydic.system.mapper.SysRoleDeptMapper;
import com.tydic.system.mapper.SysRoleMapper;
import com.tydic.system.mapper.SysRoleMenuMapper;
import com.tydic.system.mapper.SysUserRoleMapper;
import com.tydic.system.service.ISysRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色 业务层处理
 *
 * @author Lion Li
 */
@RequiredArgsConstructor
@Service
public class SysRoleServiceImpl implements ISysRoleService {

    private final SysRoleMapper baseMapper;
    private final SysRoleMenuMapper roleMenuMapper;
    private final SysUserRoleMapper userRoleMapper;
    private final SysRoleDeptMapper roleDeptMapper;


    @Override
    public Page<SysRoleVo> queryPage(QuerySysRoleBo bo) {
        Page<SysRoleVo> page = baseMapper.selectVoPage(bo.build(), buildQueryWrapper(bo));
        page.getRecords().forEach(item -> {
            item.setId(item.getRoleCode());
        });
        return page;
    }

    @Override
    public SysRoleVo getById(String roleCode) {
        SysRoleVo sysRoleVo = baseMapper.selectVoById(roleCode);
        sysRoleVo.setRoleMenuList(roleMenuMapper.selectList(Wrappers.<SysRoleMenu>lambdaQuery().eq(SysRoleMenu::getRoleCode, roleCode)));
        return sysRoleVo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(SysRoleBo bo) {
        SysRole sysRole = BeanUtil.toBean(bo, SysRole.class);
        baseMapper.insertOrUpdate(sysRole);
        roleMenuMapper.delete(Wrappers.lambdaUpdate(SysRoleMenu.class).eq(SysRoleMenu::getRoleCode, sysRole.getRoleCode()));
        if (CollUtil.isEmpty(bo.getMenuCodes())) {
            return;
        }
        List<SysRoleMenu> sysRoleMenus = bo.getMenuCodes().stream().map(item -> {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleCode(sysRole.getRoleCode());
            sysRoleMenu.setMenuCode(item);
            return sysRoleMenu;
        }).collect(Collectors.toList());
        roleMenuMapper.insertBatch(sysRoleMenus);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteByRoleCode(String roleCode) {
        roleMenuMapper.delete(Wrappers.lambdaUpdate(SysRoleMenu.class).eq(SysRoleMenu::getRoleCode, roleCode));
        baseMapper.deleteById(roleCode);
    }

    private LambdaQueryWrapper<SysRole> buildQueryWrapper(QuerySysRoleBo bo) {
        LambdaQueryWrapper<SysRole> lqw = Wrappers.lambdaQuery(SysRole.class);
        lqw.like(CharSequenceUtil.isNotBlank(bo.getRoleName()), SysRole::getRoleName, bo.getRoleName());
        lqw.like(CharSequenceUtil.isNotBlank(bo.getRoleCode()), SysRole::getRoleCode, bo.getRoleCode());
        lqw.orderByDesc(SysRole::getUpdateDate);
        return lqw;
    }
}
